"""
Module to support Synchronized classes.

Classes that inherit from L{Synchronized} will have each method wrapepd into
a mutually exclusive region using L{Reentrant Locks<threading.RLock>}.

Last Modified: $Id: synchronized.py 27 2005-05-24 22:38:32Z gustavo $

@author: U{Gustavo Sverzut Barbieri <barbieri@gmail.com>}
@license: GNU GPL
@copyright: (C) 2005 Gustavo Sverzut Barbieri
@version: $Rev: 27 $
"""









import sys
import threading
from debug import debug

class Synchronized( object ):
    """Base class to implement synchronized methods.

    Methods that start with sync_prefix will be wrapped into a
    synchronized method that uses an reentrant lock.
    """
    sync_prefix = "sync_"

    def __init__( self, lock=None ):
	self.__lock = lock or threading.RLock()
	d = {}

	def synchronized( func ):
	    def sync_func( *l, **k ):
                debug( 4, "acquire lock before: %s()" % func.func_name )
		self.__lock.acquire()
		try:
		    return func( *l, **k )
		finally:
                    debug( 4, "locked released for %s()" % func.func_name )
		    self.__lock.release()
	    # sync_func()
	    return sync_func
	# synchronized()

	for a in dir( self ):
	    v = getattr( self, a )
	    if a.startswith( self.sync_prefix ) and callable( v ):
		# create a new method
                name = a[ len( self.sync_prefix ) : ]
		d[ name ] = synchronized( v )
	# end for

	# update inner dictionary
	self.__dict__.update( d )
    # __init__()


    def get_lock( self ):
        return self.__lock
    # get_lock()
    lock = property( get_lock )
# Synchronized
